<?php


/* SVN FILE: $Id: template.php 105 2007-04-01 19:24:49Z Andy $ */

/**
 * Template (menu-data) component.
 *
 * Get and set data for use in menu items
 *
 * Copyright (c), Andy Dawson
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @filesource
 * @copyright    Copyright (c) 2007, Andy Dawson
 * @package      noswad
 * @subpackage   noswad.app.controllers.components
 * @since        Noswad site version 3
 * @version      $Revision: 105 $
 * @created      26/01/2007
 * @modifiedby   $LastChangedBy$
 * @lastmodified $Date: 2007-04-01 21:24:49 +0200 (dom, 01 abr 2007) $
 * @license      http://www.opensource.org/licenses/mit-license.php The MIT License
 */

//include_once(COMPONENTS.'template.php');
/**
 * Template component
 *
 * Queries the database and generates the data used to generate Template menu data
 */
class TemplateComponent extends Object { // extends TemplateComponent {
	var $name= 'Template';

	var $components= array (
		'Session',
		'RequestHandler'
	);

	/**
	 * Automatic processing.
	 *
	 * If set to true, the component startup method will be run.
	 * Note that the the call sequnce is
	 * 	Controller beforeFilter
	 * 	Component(s) startup
	 * 	Controller action
	 * This var is useful if the component needs some info from the controller action before it can retrieve
	 * info.
	 *
	 * @var boolean
	 * @access public
	 */
	var $auto= true;

	/**
	 * Where to store data so duplicate queries aren't necessary.
	 *
	 * Uses the cache by default, the session can also be used or disabled
	 *
	 * @var mixed cache, session or false
	 * @access public
	 */
	var $cacheMedium= 'cache';

	/**
	 * Time to cache data (if saving to the cache of course)
	 *
	 * @var string
	 * @access public
	 */
	var $cacheDuration= '+1 week';

	/**
	 * Placeholder for where to save the data
	 *
	 * @var string
	 * @access public
	 */
	var $cachePath= null;

	/**
	 * Startup method
	 *
	 * Calls the method process if and only iff the method _continue returns true
	 *
	 * @access public
	 * @param object $controller
	 * @return void result not used
	 */
	function startup(& $controller) {
		$this->controller= & $controller;
		if (is_array($this->controller->uses)) {
			foreach($this->controller->uses as $model) {
				$this->{$model} =& $this->controller->{$model};
			}
		}
		if (!$this->_continue($controller)) {
			return true;
		};
		$this->process();
	}

	/**
	 * Generic process method
	 *
	 * @access public
	 * @param object $controller
	 * @return void result not used
	 */
	function process() {
		$data= $this->_checkCache();
		if (!$data) {
			$data= $this->_getData();
			$this->_saveToCache($data);
		}
		$this->_setData($data);
	}

	function getCachePath() {
		if (!$this->cacheMedium) {
			return false;
		}
		if ($this->cachePath) {
			return $this->cachePath;
		}
		if ($this->controller->plugin) {
			$path[]= $this->controller->plugin;
		}
		$path[]= 'element_data';
		$path[]= $this->name;
		if ($this->cacheMedium == 'cache') {
			$cachePath= implode($path, '_').'.cache';
			$this->cachePath= $cachePath;
			return $cachePath;
		}
		elseif ($this->cacheMedium == 'session') {
			$cachePath= implode($path, '.');
			$this->cachePath= $cachePath;
			return $cachePath;
		}
	}
	/**
	 * Get the data from the cache
	 *
	 * If the data has already been cached, use it rather than retrieving again.
	 * If more appropriate override and use the session instead of cache.
	 *
	 * @access private
	 * @param object $controller
	 * @return void
	 */
	function _checkCache() {
		if (!$this->cacheMedium) {
			return false;
		}
		elseif ($this->cacheMedium == 'cache') {
			$cache= cache($this->getCachePath());
			if ($cache) {
				return unserialize($cache);
			} else {
				return false;
			}
		} else {
			return $this->Session->read($this->getCachePath());
		}
	}

	/**
	 * Data retrieval method
	 *
	 * return the data for this component/element
	 *
	 * @access private
	 * @return array
	 */
	function _getData() {
		return array ();
	}

	/**
	 * Pass the data to the view
	 *
	 * Passes the data to the view, to be used/ with the corresponding
	 * element
	 *
	 * @access private
	 * @param array $data
	 * @return void
	 */
	function _setData($data) {
		if ($data) {
			if (($this->cacheMedium == 'cache')&&($this->cacheDuration)) {
				$elementData['cache'] = $this->cacheDuration;
			}
			$elementData['data'] = $data;
			if (isset($data['sequence'])) {
				$elementData['sequence'] = $data['sequence'];
				unset($data['sequence']);
			}
			$this->controller->viewVars['contextMenus'][$this->name]= $elementData;
		}
	}

	/**
	 * Save the data to cache (or the session)
	 *
	 * Saves retrieved data to be used again rather than retrieving again.
	 *
	 * @access private
	 * @param array $data
	 * @return void
	 */
	function _saveToCache($data) {
		if (!$this->cacheMedium) {
			return false;
		}
		elseif ($this->cacheMedium == 'cache') {
			cache($this->getCachePath(), serialize($data), $this->cacheDuration);
		} else {
			return $this->Session->write($this->getCachePath(), $data);
		}
	}
	/**
	 * Determins whether to skip processing as part of the startup method.
	 *
	 * If the menu links aren't to be displayed, the automatic processing is bypassed.
	 * Returns false if any of the following are true:
	 * 	The current controller was called via requestAction
	 * 	The current request is an ajax call (there's no menu for an ajax call)
	 * 	The menu has been explictly disabled
	 *
	 * @access private
	 * @param object $controller
	 * @return boolean
	 */
	function _continue(& $controller) {
		if (
			(!$this->auto) ||
			isset ($controller->params['requested']) ||
			$this->RequestHandler->isAjax() ||
			($this->Session->read('Config.components') === '0')
		) {
			return false;
		}
		return true;
	}
}
?>